﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace MrBrooks.Utility
{
    /// <summary>
    /// Data helper class
    /// </summary>
    public partial class DataHelper
    {
        #region Methods
        /// <summary>
        /// Gets a boolean value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool GetBoolean(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return false;
            }
            return Convert.ToBoolean(value);
        }

        /// <summary>
        /// Gets a byte array of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] GetBytes(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return null;
            }
            return (byte[])value;
        }

        /// <summary>
        /// Gets an UTC datetime value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return DateTime.MinValue;
            }
            return DateTime.SpecifyKind((DateTime)value, DateTimeKind.Unspecified);
        }

        /// <summary>
        /// Gets an UTC datetime value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime GetUtcDateTime(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return DateTime.MinValue;
            }
            return DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
        }

        /// <summary>
        /// Gets a nullable UTC datetime value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime? GetNullableUtcDateTime(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return null;
            }
            return DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
        }

        /// <summary>
        /// Gets a decimal value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal GetDecimal(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return decimal.Zero;
            }
            return Convert.ToDecimal(value);
        }

        /// <summary>
        /// Gets a double value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static double GetDouble(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return 0.0;
            }
            return Convert.ToDouble(value);
        }

        /// <summary>
        /// Gets a GUID value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Guid GetGuid(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return Guid.Empty;
            }
            return (Guid)value;
        }

        /// <summary>
        /// Gets an integer value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int GetInt(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return 0;
            }
            //return (int)value;
            return Convert.ToInt32(value);
        }

        /// <summary>
        /// Gets an integer value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long GetLong(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return 0;
            }
            //return (int)value;
            return Convert.ToInt64(value);
        }

        /// <summary>
        /// Gets a nullable integer value of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int? GetNullableInt(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return null;
            }
            return (int)value;
        }

        /// <summary>
        /// Gets a string of a data reader by a column name
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetString(object value)
        {
            if (Convert.IsDBNull(value))
            {
                return string.Empty;
            }
            return Convert.ToString(value);
        }

        /// <summary>
        /// 得到workdate
        /// </summary>
        /// <returns></returns>
        public static int GetWorkDate()
        {
            int workingDate = 19000000;
            DateTime time = DateTime.Now;
            int hour = Convert.ToInt32(time.ToString("HH"));
            if (hour >= 12)
            {
                workingDate = Convert.ToInt32(time.ToString("yyyyMMdd"));
            }
            else
            {
                workingDate = Convert.ToInt32(time.AddDays(-1).ToString("yyyyMMdd"));
            }
            return workingDate;
        }
        #endregion

        #region .Copy.
        /// <summary>
        /// 深复制(确保可被序列化)
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public static T CloneDeeply<T>(T items)
        {
            // 创建内存流
            var ms = new MemoryStream();
            // 以二进制格式进行序列化
            var bf = new BinaryFormatter();
            bf.Serialize(ms, items);
            // 反序列化当前实例到一个object
            ms.Seek(0, 0);
            var obj = bf.Deserialize(ms);
            // 关闭内存流
            ms.Close();
            return (T)obj;
        }

        #endregion
    }
}
